/**
 * util 工具
 */
 import bwLocalStorage from "./localStorage";
 import common from "./common";
 import global from "./global";
 
 var isLimit = false;
 var prefabObj = {};
 var prefabLoadObj = {};  // 记录是否加载回调 (点击后快速关闭情况：异步加载的prefab还没返回，调用节点onDestroy了才返回回调)
 var prefabTimeObj = {};  // 记录加载预制体时间，避免短时间频繁调用
 const BWU = {
     
     globalEventOn(option = {}) {
         global.event.on(option.name, option.fn, option.target);
     },
     globalEventEmit(option = {}) {
         return global.event.emit(option.name, option.option);
     },
     globalEventOff(option = {}) {
         global.event.off(option.name, option.target);
     },    
     //查找字符串中的字符串第n次出现的位置
     findString(str, cha, num) {
         let times = num ? num : 1;
         var x = str.indexOf(cha);
         for (var i = 0; i < times - 1; i++) {
             x = str.indexOf(cha, x + 1);
         }
         return x;
     },
     //深度拷贝(递归)
     copy(obj) {
         let objArray = Array.isArray(obj) ? [] : {};
         if (obj && typeof obj === "object") {
             Object.keys(obj).forEach(key => {
                 if (obj[key] && typeof obj[key] === "object") {
                     objArray[key] = this.copy(obj[key]);
                 } else {
                     objArray[key] = obj[key];
                 }
             });
         }
         return objArray;
     },
     /**
      * 
      * @param {*} str 显示的文本
      * @param {
      *  type :1 //默认1 用于切换toast移动规则  1：一半停留 一半上浮  2：停留
      *  bgType:1 //默认1 用于显示toast背景 0：无背景 1：默认背景 2：广播背景
      *  offsetY:10// 默认无  用于设置y轴偏移 number类型  
      * } obj 
      */
     toast(str, obj = {}) {
         let option = {
             type: 1,
             bgType: 1,
             ...obj,
         }
         str = this.exchangeStString(str);
         BWU.eventGlobalEmit(common.globalEventType.toast, {
             title: str,
             option: option,
         });
     },
     instanceof(opt, str) {
         let obj = {
             'String': '[object String]',
             'Number': '[object Number]',
             'Boolean': '[object Boolean]',
             'Symbol': '[object Symbol]',
             'Undefined': '[object Undefined]',
             'Null': '[object Null]',
             'Function': '[object Function]',
             'Date': '[object Date]',
             'Array': '[object Array]',
             'RegExp': '[object RegExp]',
             'Error': '[object Error]',
             'HTMLDocument': '[object HTMLDocument]',
             'global': '[object global]',
             'Object': '[object Object]',
         }
         if (Object.prototype.toString.call(str) === obj['String']) {
             if (Object.prototype.toString.call(opt) === obj[str]) {
                 return true;
             }
         }
         if (Object.prototype.toString.call(str) === obj['Array']) {
             let flag = false;
             for (let i = 0; i < str.length; i++) {
                 let item = str[i];
                 if (Object.prototype.toString.call(opt) === obj[item]) {
                     flag = true;
                     break;
                 }
             }
             return flag;
         }
 
         return false;
     },
     //点击事件 装饰器 
     //time : 单位 秒 
     isClickLimit(time = common.TIME.limitTime) {
         if (isLimit) { return true; }
         isLimit = true;
         setTimeout(() => {
             isLimit = false;
         }, time * 1000);
         return false;
     },
     btnClickLimit(node, target, time = common.TIME.limitTime) {
         let btn = node.getComponent(cc.Button);
         if (btn) {
             btn.interactable = false;
             target.scheduleOnce(() => {
                 if (btn && btn.isValid) {
                     btn.interactable = true;
                 }
             }, time);
         }
     },
     
     /**
      * 获取节点的相对坐标
      * 世界坐标转相对坐标
      * 
      */
     getSpaceAR(node, word) {
         //获取指定坐标的 世界坐标
         let worldPos = node.convertToWorldSpaceAR(cc.v2(0, 0));
         //获取当前节点 世界坐标的 相对坐标
         return word.convertToNodeSpaceAR(worldPos);
     },
     /**
     * 缓存 读写
     * @param {*} key 
     */
     getCryptItem(key) {
         let value = bwLocalStorage.getItem(key);
         if (!value) {
             return null;
         }
         return JSON.parse(crypt.dncodeBase64(value));
     },
     setCryptItem(key, value) {
         let val = crypt.encodeBase64(JSON.stringify(value));
         bwLocalStorage.setItem(key, val);
     },
     getItem(key) {
         let value = bwLocalStorage.getItem(key);
         if (!value || value == 'undefined') {
             return null;
         }
         return JSON.parse(value);
     },
     setItem(key, value) {
         bwLocalStorage.setItem(key, JSON.stringify(value));
     },
     removeItem(key) {
         bwLocalStorage.removeItem(key);
     },
     getType(type) {
         let t = /^\[object\s(.*)\]$/.exec(Object.prototype.toString.call(type))[1];
         return t;
     },
     /**
      * 倒计时转换
      * @param {} t 
      */
     formatSeconds(t) {
         let mi = 60, hh = mi * 60, dd = hh * 24;
         let h = this.formatBit(Math.floor(t / hh)),
             m = this.formatBit(Math.floor((t - h * hh) / mi)),
             s = this.formatBit(Math.floor((t - h * hh - m * mi)));
         let tstr = h + ':' + m + ":" + s;
         return tstr;
     },
     formatBit(v) {
         v = +v
         return v > 9 ? v : '0' + v
     },        
     /**
      * 根据指定的最小值，和最大值，生成一个随机整数 如参数为  0,100       可以取到0-99之间任意整数
      * @param {*} min 
      * @param {*} max 取不到最大值
      */
     getRandom(min, max) {
         return Math.floor(Math.random() * (max - min) + min);
     },
     
     // 加载预制体
     toLoadPrefab(name, target, callback) {
        
         return new Promise((resolve, reject) => {
             let prefabData = prefabObj[name];
             if (prefabData) {
                 prefabData.addRef();
                 callback && callback(prefabData);
                 resolve(prefabData);
             } else {
                 // 处理短时间触发多次的情况（间隔要大于200ms） - 快速点击情况
                 let preLoadedTime = prefabTimeObj[name] || 0;
                 let currLoadedTime = new Date().getTime();
                 if ((currLoadedTime - preLoadedTime) > 200) {
                     prefabLoadObj[name] = true;
                     prefabTimeObj[name] = currLoadedTime;
                     cc.resources.load(`prefab/${name}`, cc.Prefab, (err, prefab) => {
                         if (prefab) {
                             prefab.addRef();
                             log("name = " + name + ", refCount = " + prefab.refCount);
                             prefabObj[name] = prefab;
                             if (prefabLoadObj[name]) {
                                 if (target.node) {
                                     callback && callback(prefab);   // 有必要再传入一个加载预制体的this，用于判断对应页面是否失效，从而进行回调或者预制体销毁等
                                     resolve(prefab);
                                     // log('加载后资源引用', cc.assetManager.assets)
                                 } else {
                                     this.toReleasePrefab(name);
                                     reject();
                                 }
                             } else {
                                 this.toReleasePrefab(name);
                                 reject();
                             }
                         } else {
                             log("未找到prefab - " + name);
                             reject();
                         }
                     });
                 } else {
                     log("频繁加载同一个预制体 - " + name);
                     reject();
                 }
             }
         }).catch(() => { })
     },
     // 释放预制体
     toReleasePrefab(name) { 
         let prefab = prefabObj[name];
         if (prefab) {
             prefab.decRef();
             log("name = " + name + ", refCount = " + prefab.refCount);
             if (prefab.refCount == 0) {
                 prefab = null;
                 delete prefabObj[name];
                 delete prefabLoadObj[name];
             }
         } else {
             delete prefabLoadObj[name];
         }
     },        
 }
 
 export default BWU;